#ifndef STACKINT_H
#define STACKINT_H

#include "ErrorType.h"
#include <stdio.h>
#include <stdlib.h>

#define MAXSIZE 1000

#define TRUE 1
#define FALSE 0

typedef int bool;
typedef int StkElementType;
typedef struct SNode *Stack;
struct SNode{
    StkElementType data;
    struct SNode *Next;
};

// Create an empty stack the largest length of which is MAXSIZE.
Stack CreateStack();

// Judge whether stack S is full or not.
bool StackFull(Stack S);

// Judge whether Stack S is empty or not.
bool StackEmpty(Stack S);

// Push element item into the stack.
bool Push(Stack S, StkElementType item);

// Delete and return the top element of stack.
StkElementType Pop(Stack S);

// Return the length of the stack.
int StackLength(Stack S);

// Return the top element of the stack.
StkElementType getTop(Stack S);

// Clear the elements stored in the stack
bool ClearStack(Stack S);

// Destroy the stack
bool DestroyStack(Stack S);

// void ShowList(Stack S);
#endif // STACKINT_H

Stack CreateStack(){
    Stack S = (Stack) malloc(sizeof( struct SNode ));
    S->Next = NULL;
    return S;
}

bool StackFull(Stack S){
    if (StackEmpty(S)) return FALSE;
    int i = StackLength(S);
    if(i == MAXSIZE)
        return TRUE;
    else
        return FALSE;
}

bool StackEmpty(Stack S){
    if(!(S->Next))
        return TRUE;
    else
        return FALSE;
}

bool Push(Stack S, StkElementType item){
    struct SNode *tmpCell = (struct SNode *)malloc(sizeof(struct SNode *));
    tmpCell->data = item;
    tmpCell->Next = S->Next;
    S->Next = tmpCell;
    return TRUE;
}

StkElementType Pop(Stack S){
    struct SNode *topCell;
    StkElementType top;
    if (StackEmpty(S)) {
        printf("Empty stack!\n");
        return NULL;
    }
    else {
        topCell = S->Next;
        top = topCell->data;
        S->Next = topCell->Next;
        free(topCell);
        return top;
    }
}

int StackLength(Stack S) {
    int i;
    for(i = 0; S != NULL ; S = S->Next, i++);
    return i;
}

StkElementType getTop(Stack S) {
    if(StackEmpty(S) == TRUE) {
        printf("Operation Failed!\nError Code %02x!\n",INVALID);
        return NULL;
    }
    else{
        return S->data;
    }
}

bool ClearStack(Stack S) {
    struct SNode *temp = S;
    while (S != NULL)
    {
        S = S->Next;
        temp->data = 0;
        temp = S;
    }

    if (S == NULL)
    {
        return TRUE;
    }
    else return FALSE;
}

bool DestroyStack(Stack S) {
    struct SNode *temp = S;
    while (S != NULL)
    {
        S = S->Next;
        free(temp);
        temp = S;
    }

    if (S == NULL)
    {
        return TRUE;
    }
    else return FALSE;
}
